package com.pactera.madp.cp.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.common.core.util.R;
import com.pactera.madp.common.security.util.SecurityUtils;
import com.pactera.madp.cp.api.dto.taskpublish.TaskAddDTO;
import com.pactera.madp.cp.api.dto.taskpublish.TaskQueryDTO;
import com.pactera.madp.cp.api.em.taskpublish.TypeEnum;
import com.pactera.madp.cp.api.entity.BaseEntity;
import com.pactera.madp.cp.api.entity.WorkEmployeeEntity;
import com.pactera.madp.cp.api.entity.taskpublish.ReadCountEntity;
import com.pactera.madp.cp.api.entity.taskpublish.TaskEntity;
import com.pactera.madp.cp.api.entity.workroom.WorkInternalGroupEntity;
import com.pactera.madp.cp.api.page.SubPage;
import com.pactera.madp.cp.api.vo.taskpublish.*;
import com.pactera.madp.cp.api.vo.workroom.WorkInternalGroupDetailsVO;
import com.pactera.madp.cp.common.config.FileUploadConfig;
import com.pactera.madp.cp.common.constant.TaskPublsih;
import com.pactera.madp.cp.common.util.WxApiUtils;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.mapper.taskpublish.TaskMapper;
import com.pactera.madp.cp.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.*;

/**
 * @date: 2021/8/10 11:27
 * @description:
 */
@Service
@Slf4j
public class TaskPublishServiceImpl extends ServiceImpl<TaskMapper, TaskEntity> implements ITaskPublishService {

    @Autowired
    private ITaskReadCountService taskReadCountService;
    @Autowired
    private WorkInternalGroupService workInternalGroupService;
    @Autowired
    private FileUploadConfig fileUploadConfig;
    @Autowired
    private IWorkEmployeeService workEmployeeService;
    @Autowired
    private ICorpService corpService;

    @Override
    public boolean createTask(TaskAddDTO taskAddDTO) {
        String username = SecurityUtils.getUser().getUsername();
        TaskEntity taskEntity = new TaskEntity();
        Object json =JSONObject.toJSON(taskAddDTO.getContent());
        taskEntity.setCreateUser(username);
        String s = json.toString();
        String strip = StringUtils.strip(s, "[]");
        JSONObject jsonObject = JSONObject.parseObject(strip);
        taskEntity.setType(Integer.valueOf(Integer.valueOf(jsonObject.get("type").toString())));
        taskEntity.setContent(json.toString());
        taskEntity.setIsCount(taskAddDTO.getIsCount());
        String ids = taskAddDTO.getIds().toString();
        List<String> groupChatName = new ArrayList();
        taskAddDTO.getIds().forEach(one->{
            WorkInternalGroupDetailsVO details = workInternalGroupService.getDetails(one);
            groupChatName.add(details.getName());
        });
        taskEntity.setPublishRange(groupChatName.toString());
        taskEntity.setIds(ids);
        taskEntity.setStatus(Integer.valueOf(TaskPublsih.TASK_STATUS_PUBLISH_OFF));
        taskEntity.setCorpId(CorpContextHolder.getCorpId());
        taskEntity.setCollectionTitle(taskAddDTO.getCollectionTitle());
        if(save(taskEntity)){
            if (saveMediumById(taskEntity.getId())){
                return true;
            }else{
                removeById(taskEntity.getId());
                throw new CheckedException("临时素材上传失败，请检查上传素材是否符合");
            }
        }else
        return false;
    }

    @Override
    public R<Page<List<TaskQueryVO>>> pageQuery(Page page, TaskQueryDTO dto) {
        return pageQueryHandle(page, dto);
    }

    @Override
    public boolean updateMediumById(TaskEntity entity) {
        return  this.updateById(entity);
    }

    @Override
    public void saveMediaId() {
        List<TaskEntity> list = this.list(Wrappers.<TaskEntity>lambdaQuery().eq(TaskEntity::getCorpId,CorpContextHolder.getCorpId()));
        for (TaskEntity entity:list) {
            JSONArray objects = JSONArray.parseArray(entity.getContent());
            LinkedList<MediumVO> VOS = new LinkedList<>();
            for (int i = 0; i < objects.size(); i++) {
                MediumVO vo = new MediumVO();
                JSONObject jsonObject = JSONObject.parseObject(objects.get(i).toString());
                Integer type = jsonObject.getInteger("type");
                if(type == 2||type == 3){
                    vo.setType(type);
                    vo.setTypeText(TypeEnum.getTypeByCode(type));
                    String types = null;
                    switch (type){
                        case 2:
                            types = "image";
                            break;
                        case 3:
                            types = "file";
                            break;
                    }
                    JSONObject object = JSONObject.parseObject(jsonObject.getString("content"));
                    String url = object.getString("url");
                    String[] split = url.split("/");
                    String fileUrl = fileUploadConfig.getRealPath() + File.separator + "/files/corp-"+CorpContextHolder.getCorpId() + "/" +split[split.length-1];
                    File file = new File(fileUrl);
                    log.info("开始上传临时素材");
                    String  s = null;
                    try {
                        log.info("文件名为："+file.getName());
                        s = WxApiUtils.uploadImageToTemps(entity.getCorpId(), file,types);
                    }catch (NullPointerException e){
                        log.info("临时素材库已有素材，无法上传");
                        continue;
                    }
                    vo.setMediaId(s);
                    VOS.add(vo);
                }
                TaskEntity enyity = new TaskEntity();
                enyity.setMediaId(JSONUtil.toJsonStr(VOS));
                enyity.setId(enyity.getId());
                updateMediumById(enyity);
            }
        }
    }

    @Override
    public boolean saveMediumById(Integer id) {
            TaskEntity entity = getOne(Wrappers.<TaskEntity>lambdaQuery().eq(TaskEntity::getId,id));
            JSONArray objects = JSONArray.parseArray(entity.getContent());
            LinkedList<MediumVO> VOS = new LinkedList<>();
            for (int i = 0; i < objects.size(); i++) {
                MediumVO vo = new MediumVO();
                JSONObject jsonObject = JSONObject.parseObject(objects.get(i).toString());
                Integer type = jsonObject.getInteger("type");
                if(type == 2||type == 3){
                    vo.setType(type);
                    vo.setTypeText(TypeEnum.getTypeByCode(type));
                    String types = null;
                    switch (type){
                        case 2:
                            types = "image";
                            break;
                        case 3:
                            types = "file";
                            break;
                    }
                    JSONObject object = JSONObject.parseObject(jsonObject.getString("content"));
                    String url = object.getString("url");
                    String[] split = url.split("/");
                    String fileUrl = fileUploadConfig.getRealPath() + File.separator + "/files/corp-"+CorpContextHolder.getCorpId() + "/" +split[split.length-1];
                    File file = new File(fileUrl);
                    log.info("开始上传临时素材");
                    String  s = null;
                    try {
                        log.info("文件名为："+file.getName());
                        s = WxApiUtils.uploadImageToTemps(entity.getCorpId(), file,types);
                    }catch (NullPointerException e){
                        log.info("临时素材库已有素材，无法上传");
                        continue;
                    }
                    if (StrUtil.isBlank(s)){
                        return false;
                    }
                    vo.setMediaId(s);
                    VOS.add(vo);
                }
                TaskEntity entitys = new TaskEntity();
                entitys.setMediaId(JSONUtil.toJsonStr(VOS));
                entitys.setId(entity.getId());
             return updateMediumById(entitys);
            }
        return false;
    }

    @Override
    public R sendTaskToChatGroup(Integer id) {
        Integer corpId = CorpContextHolder.getCorpId();
        String wxCorpId = corpService.getById(corpId).getWxCorpId();
        TaskEntity taskEntity = this.getOne(Wrappers.<TaskEntity>lambdaQuery().eq(TaskEntity::getId, id).eq(TaskEntity::getCorpId,corpId ));
        String ids = taskEntity.getIds();
        Integer type = taskEntity.getType();
        List<Integer> idList = JSONUtil.toList(JSONUtil.parseArray(ids), Integer.class);
        JSONObject jsonObject = new JSONObject();
        List<WorkInternalGroupEntity> entities = workInternalGroupService.list(Wrappers.<WorkInternalGroupEntity>lambdaQuery()
                .eq(WorkInternalGroupEntity::getCorpId, corpId)
                .in(WorkInternalGroupEntity::getId, idList));
        entities.forEach(en->{
            if(type==1) {
                HashMap<String, String> hashMap = new HashMap<>();
                JSONArray objects = JSONArray.parseArray(taskEntity.getContent());
                JSONObject object = JSONObject.parseObject(objects.get(0).toString());
                JSONObject content = JSONObject.parseObject(object.getString("content"));
                String contentText = content.getString("contentText");
                hashMap.put("content", contentText);
                jsonObject.put("chatid", en.getChatId());
                jsonObject.put("msgtype", "text");
                jsonObject.put("text", hashMap);
            }else if(type==2){
                HashMap<String, String> hashMap = new HashMap<>();
                JSONArray objects = JSONArray.parseArray(taskEntity.getMediaId());
                JSONObject object = JSONObject.parseObject(objects.get(0).toString());
                String mediaId = object.getString("mediaId");
                hashMap.put("media_id", mediaId);
                jsonObject.put("chatid", en.getChatId());
                jsonObject.put("msgtype", "image");
                jsonObject.put("image", hashMap);
            }else if(type==3){
                HashMap<String, String> hashMap = new HashMap<>();
                JSONArray objects = JSONArray.parseArray(taskEntity.getMediaId());
                JSONObject object = JSONObject.parseObject(objects.get(0).toString());
                String mediaId = object.getString("mediaId");
                hashMap.put("media_id", mediaId);
                jsonObject.put("chatid", en.getChatId());
                jsonObject.put("msgtype", "file");
                jsonObject.put("file", hashMap);
            }else if(type == 4){
                HashMap<String, String> hashMap = new HashMap<>();
                JSONArray objects = JSONArray.parseArray(taskEntity.getContent());
                JSONObject object = JSONObject.parseObject(objects.get(0).toString());
                JSONObject content = JSONObject.parseObject(object.getString("content"));
                String title = content.getString("title");
                String description = content.getString("description");
                String link = content.getString("link");
                String imgurl = content.getString("imgurl");
                hashMap.put("title",title);
                hashMap.put("url", link);
                hashMap.put("description",description);
                hashMap.put("picurl",imgurl);
                jsonObject.put("chatid", en.getChatId());
                jsonObject.put("msgtype", "news");
                JSONObject news = new JSONObject();
                JSONArray array = new JSONArray();
                news.put("articles", array);
                array.add(hashMap);
                jsonObject.put("news", news);
            } else {
                throw new CheckedException("类型不满足");
            }
            String errcode = WxApiUtils.sendMsgToGroupChat(jsonObject, corpId,wxCorpId);
            if(errcode != null && "0".equals(errcode)){

            }
        });
        return R.ok();
    }

    @Override
    public TaskDetailVO detailShow(Integer id) {
        TaskEntity taskEntity = this.baseMapper.selectOne(Wrappers.<TaskEntity>lambdaQuery()
                .eq(TaskEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(TaskEntity::getId, id));
        TaskDetailVO detailVO = new TaskDetailVO();
        if (taskEntity == null){
            return detailVO;
        }
        detailVO.setId(taskEntity.getId());
        detailVO.setCollectionTitle(taskEntity.getCollectionTitle());
        detailVO.setContent(JSONArray.parseArray(taskEntity.getContent()));
        return detailVO;
    }

    @Override
    public R getTaskReadDetail(Integer id) {
        Integer corpId = CorpContextHolder.getCorpId();
        //查询已阅读成员
        ReadCountEntity one = taskReadCountService.getOne(Wrappers.<ReadCountEntity>lambdaQuery()
                .eq(ReadCountEntity::getTaskId, id)
                .eq(ReadCountEntity::getCorpId, corpId));
        EmployeeListVO vo = new EmployeeListVO();
        if(one==null||StrUtil.isBlank(one.getReadEmployee())){
            return R.ok(vo);
        }
        List<String> employee = JSONUtil.toList(JSONUtil.parseArray(one.getReadEmployee()), String.class);
        List<WorkEmployeeEntity> readEmployeeList = workEmployeeService.list(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                .eq(WorkEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                .in(WorkEmployeeEntity::getWxUserId, employee));

        //根据任务id查询群聊id
        TaskEntity taskEntity = this.baseMapper.selectOne(Wrappers.<TaskEntity>lambdaQuery()
                .eq(TaskEntity::getCorpId, corpId)
                .eq(TaskEntity::getId, id));
        String ids = taskEntity.getIds();
        List<Integer> idList = JSONUtil.toList(JSONUtil.parseArray(ids), Integer.class);

        //根据群聊id查询所有群聊
        List<WorkInternalGroupEntity> entities = workInternalGroupService.list(Wrappers.<WorkInternalGroupEntity>lambdaQuery()
                .eq(WorkInternalGroupEntity::getCorpId, corpId)
                .in(WorkInternalGroupEntity::getId, idList));

        //未阅读成员列表
        LinkedList<String> noReadList = new LinkedList<>();
        //已阅读成员列表
        LinkedList<String> alreadyReadList = new LinkedList<>();
        //群聊id列表
        LinkedList<String> chatIdList = new LinkedList<>();
        Map<String,Object> noReadMap = new HashMap<>();
        Map<String,Object> alreadyRead = new HashMap<>();
        for (int i = 0; i < entities.size(); i++) {
            //查询所有群聊成员
            List<WorkEmployeeEntity> list = workEmployeeService.list(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                    .in(WorkEmployeeEntity::getWxUserId, JSONArray.parseArray(entities.get(i).getUserList(), String.class)));
            list.forEach(en->{
                boolean isAlready = false;
                for(WorkEmployeeEntity alreadyEmp : readEmployeeList) {
                    if(en.getWxUserId().equals(alreadyEmp.getWxUserId())) {
                        isAlready = true;
                    }
                }
                if(isAlready) {
                    alreadyRead.put(en.getName(),null);
                }else{
                    noReadMap.put(en.getName(),null);
                }
            });
            String chatId = entities.get(i).getChatId();
            chatIdList.add(chatId);
        }
        noReadList.addAll(noReadMap.keySet());
        alreadyReadList.addAll(alreadyRead.keySet());

        vo.setChatId(chatIdList);
        vo.setAlreadyReadList(alreadyReadList);
        vo.setNoReadList(noReadList);
        return R.ok(vo);
    }

    private R<Page<List<TaskQueryVO>>> pageQueryHandle (Page page, TaskQueryDTO dto){
        LambdaQueryChainWrapper<TaskEntity> wrapper = lambdaQuery();
        wrapper.orderByDesc(TaskEntity::getCreateTime);
        wrapper.eq(TaskEntity::getCorpId,CorpContextHolder.getCorpId());
        //判断创建人是否为空
        if(!StringUtils.isBlank(dto.getEmployeeName()))
            wrapper.like(TaskEntity::getCreateUser,dto.getEmployeeName());
        //判断查询时间
        if (dto.getStartTime() != null && dto.getEndTime() != null && !dto.getEndTime().equals("") && !dto.getStartTime().equals("")){
            wrapper.gt(BaseEntity::getCreateTime,dto.getStartTime()+" 00:00:00");
            wrapper.lt(BaseEntity::getCreateTime,dto.getEndTime()+ " 23:59:59");
        }
        IPage page1 = wrapper.page(page);
        System.out.println("page1 = " + page1.getRecords());
        List<TaskQueryVO> taskQueryVOS = new LinkedList<>();
        List<TaskEntity> entityList = page1.getRecords();
        for(TaskEntity entity:entityList){
            String ids = entity.getIds();
            List<String> nameGroupList = new ArrayList();
            List<Integer> id = JSONUtil.toList(JSONUtil.parseArray(ids), Integer.class);
            System.out.println("integers = " + id);
            id.forEach(one->{
                WorkInternalGroupDetailsVO details = workInternalGroupService.getDetails(one);
                nameGroupList.add(details.getName());
            });
            TaskQueryVO vo = new TaskQueryVO();
            vo.setId(entity.getId());
            vo.setCreateUser(entity.getCreateUser());
            vo.setType(entity.getType());
            vo.setTypeDesc(TypeEnum.getTypeByCode(entity.getType()));
            vo.setCollectionTitle(entity.getCollectionTitle());
            vo.setContent(JSONArray.parseArray(entity.getContent()));
            vo.setPublishRange(nameGroupList);
            vo.setIsCount(entity.getIsCount());
            vo.setIds(entity.getIds());
            vo.setStatus(entity.getStatus());
            vo.setCreateTime(entity.getCreateTime());
            taskQueryVOS.add(vo);
        }
        SubPage subPage = new SubPage();
        subPage.setRecords(taskQueryVOS);
        subPage.setCurrent(page.getCurrent());
        subPage.setSize(page.getSize());
        subPage.setTotal(page.getTotal());
        return R.ok(subPage);
    }


}
